package com.aoxiang.zbox.common.util;

import cn.hutool.json.JSONObject;
import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTPayload;
import cn.hutool.jwt.JWTUtil;
import com.aoxiang.zbox.common.exception.BaseException;
import com.aoxiang.zbox.common.exception.ErrorCodeEnum;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

public class JwtUtil {
    public static final String USER_ID = "userId";
    public static final String USERNAME = "username";
    private final String secret;
    private final Integer expireTime;

    public JwtUtil(String secret, Integer expireTime) {
        this.secret = secret;
        this.expireTime = expireTime;
    }

    /**
     * 创建token
     *
     * @param id
     * @param username
     * @return
     */
    public String createToken(Long id, String username) {
        LocalDateTime now = LocalDateTime.now();
        Map<String, Object> payload = new HashMap<>();
        // 签发时间
        payload.put(JWTPayload.ISSUED_AT, now);
        // 过期时间
        if (expireTime != null) {
            LocalDateTime expTime = now.plusHours(expireTime);
            payload.put(JWTPayload.EXPIRES_AT, expTime);
        }
        // 生效时间
        payload.put(JWTPayload.NOT_BEFORE, now);
        // 内容
        payload.put(USER_ID, id);
        payload.put(USERNAME, username);
        return JWTUtil.createToken(payload, secret.getBytes());
    }

    /**
     * 校验token
     *
     * @param token
     * @return
     */
    public boolean validate(String token) {
        try {
            JWT jwt = JWTUtil.parseToken(token).setKey(secret.getBytes());
            return jwt.validate(0);
        } catch (Exception e) {
            throw new BaseException(ErrorCodeEnum.TOKEN_EXPIRED);
        }
    }

    public JSONObject getJsonObject(String token) {
        JWT jwt = JWTUtil.parseToken(token).setKey(secret.getBytes());
        JSONObject payloads = jwt.getPayloads();
        payloads.remove(JWTPayload.ISSUED_AT);
        payloads.remove(JWTPayload.EXPIRES_AT);
        payloads.remove(JWTPayload.NOT_BEFORE);
        return payloads;
    }

    public Map<String, Object> getUser(String token) {
        JWT jwt = JWTUtil.parseToken(token).setKey(secret.getBytes());
        JSONObject payloads = jwt.getPayloads();
        Long id = ((Integer) payloads.get(USER_ID)).longValue();
        String username = (String) payloads.get(USERNAME);
        return new HashMap<String, Object>() {{
            put(USER_ID, id);
            put(USERNAME, username);
        }};
    }

    public Long getUserId(String token) {
        JWT jwt = JWTUtil.parseToken(token).setKey(secret.getBytes());
        JSONObject payloads = jwt.getPayloads();
        Number id = (Number) payloads.get(USER_ID);
        return id != null ? id.longValue() : null;
    }

    public String getUsername(String token) {
        JWT jwt = JWTUtil.parseToken(token).setKey(secret.getBytes());
        JSONObject payloads = jwt.getPayloads();
        return (String) payloads.get(USERNAME);
    }
}
